using jiuyuan.数据.用户类;
using jiuyuan.数据.玩家类;
using jiuyuan.数据.共享类;
using jiuyuan.数据.基础数据类; // 添加基础数据类引用
using Microsoft.EntityFrameworkCore;
using System.Security.Cryptography;
using System.Text;

namespace jiuyuan.服务
{
    public interface IUserService
    {
        Task<用户?> 用户登录(string 用户名, string 密码);
        Task<用户> 用户注册(string 用户名, string 密码, string 邮箱);
        Task<玩家角色> 创建玩家角色(Guid 用户Id, string 角色名, string 职业);
        Task<用户?> 获取用户信息(Guid userId);
        Task<List<玩家角色>> 获取用户角色列表(Guid userId);
        Task<bool> 验证管理员权限(Guid userId);
        Task<玩家> 创建玩家实例(玩家角色 角色);
    }

    public class 用户服务(游戏数据库上下文 数据库上下文) : IUserService
    {

        /// <summary>
        /// 哈希密码
        /// </summary>
        private string 哈希密码(string 密码)
        {
            // 简单的SHA256哈希，实际应用中应使用BCrypt或类似的强哈希算法
            // 计算哈希值
            byte[] bytes = SHA256.HashData(Encoding.UTF8.GetBytes(密码));

            // 转换为十六进制字符串
            StringBuilder builder = new();
            for (int i = 0; i < bytes.Length; i++)
            {
                builder.Append(bytes[i].ToString("x2"));
            }
            return builder.ToString();
        }

        /// <summary>
        /// 用户登录
        /// </summary>
        public async Task<用户?> 用户登录(string 用户名, string 密码)
        {
            var 用户 = await 数据库上下文.用户表
                .Include(u => u.玩家角色列表)
                .ThenInclude(pr => pr.游戏玩家)
                .FirstOrDefaultAsync(u => u.用户名 == 用户名);

            if (用户 == null)
                return null;

            // 验证密码
            var 哈希后的密码 = 哈希密码(密码);
            if (用户.密码哈希 != 哈希后的密码)
                return null;

            // 更新最后登录时间
            用户.最后登录时间 = DateTime.Now; 
            await 数据库上下文.SaveChangesAsync();

            return 用户;
        }

        /// <summary>
        /// 用户注册
        /// </summary>
        public async Task<用户> 用户注册(string 用户名, string 密码, string 邮箱)
        {
            // 检查用户名是否已存在
            if (await 数据库上下文.用户表.AnyAsync(u => u.用户名 == 用户名))
                throw new Exception("用户名已存在");

            // 检查邮箱是否已存在
            if (await 数据库上下文.用户表.AnyAsync(u => u.邮箱 == 邮箱))
                throw new Exception("邮箱已被注册");

            var 哈希后的密码 = 哈希密码(密码);

            var 新用户 = new 用户
            {
                用户名 = 用户名,
                密码哈希 = 哈希后的密码,
                邮箱 = 邮箱,
                是管理员 = false, // 默认不是管理员
                创建时间 = DateTime.Now, // 使用UTC时间
                最后登录时间 = DateTime.Now // 使用UTC时间
            };

            await 数据库上下文.用户表.AddAsync(新用户);
            await 数据库上下文.SaveChangesAsync();

            return 新用户;
        }

        /// <summary>
        /// 创建玩家角色
        /// </summary>
        public async Task<玩家角色> 创建玩家角色(Guid 用户Id, string 角色名, string 职业)
        {
            // 检查角色名是否已存在
            if (await 数据库上下文.玩家角色表.AnyAsync(r => r.角色名 == 角色名))
                throw new Exception("角色名已存在");

            // 创建对应的玩家实例
            var 玩家实例 = new 玩家
            {
                名称 = 角色名,
                等级 = 1,
                经验值 = 0,
                单位类型 = 战斗单位类型.玩家,
                头像 = "default_avatar",
                当前生命值 = 100, // 初始生命值
                当前魔法值 = 50,  // 初始魔法值
                基础属性 = new 属性配置
                {
                    生命值 = 100,
                    魔法值 = 50,
                    物理攻击 = 10,
                    物理防御 = 5,
                    火属性攻击 = 0,
                    水属性攻击 = 0,
                    风属性攻击 = 0,
                    土属性攻击 = 0,
                    火属性抗性 = 0,
                    水属性抗性 = 0,
                    风属性抗性 = 0,
                    土属性抗性 = 0,
                    速度 = 10,
                    幸运值 = 5
                }
            };

            // 添加玩家实例到数据库
            await 数据库上下文.玩家表.AddAsync(玩家实例);
            await 数据库上下文.SaveChangesAsync();

            var 新角色 = new 玩家角色
            {
                角色名 = 角色名,
                等级 = 1,
                职业 = 职业,
                用户Id = 用户Id,
                游戏玩家Id = 玩家实例.Id,
                创建时间 = DateTime.Now // 使用UTC时间
            };

            await 数据库上下文.玩家角色表.AddAsync(新角色);
            await 数据库上下文.SaveChangesAsync();

            return 新角色;
        }

        /// <summary>
        /// 创建玩家实例
        /// </summary>
        public async Task<玩家> 创建玩家实例(玩家角色 角色)
        {
            // 创建新的玩家实例（游戏副本或战斗中使用）
            var 玩家实例 = new 玩家
            {
                名称 = 角色.角色名,
                等级 = 角色.等级,
                经验值 = 0, // 每次创建新实例时经验值重置
                单位类型 = 战斗单位类型.玩家,
                头像 = "default_avatar",
                当前生命值 = 100, // 初始生命值
                当前魔法值 = 50,  // 初始魔法值
                基础属性 = new 属性配置
                {
                    生命值 = 100,
                    魔法值 = 50,
                    物理攻击 = 10,
                    物理防御 = 5,
                    火属性攻击 = 0,
                    水属性攻击 = 0,
                    风属性攻击 = 0,
                    土属性攻击 = 0,
                    火属性抗性 = 0,
                    水属性抗性 = 0,
                    风属性抗性 = 0,
                    土属性抗性 = 0,
                    速度 = 10,
                    幸运值 = 5
                }
            };

            // 复制基础属性（如果需要的话）
            // 这里可以根据需要复制角色的装备、技能等信息

            await 数据库上下文.玩家表.AddAsync(玩家实例);
            await 数据库上下文.SaveChangesAsync();

            return 玩家实例;
        }

        /// <summary>
        /// 获取用户信息
        /// </summary>
        public async Task<用户?> 获取用户信息(Guid userId)
        {
            return await 数据库上下文.用户表
                .Include(u => u.玩家角色列表)
                .ThenInclude(pr => pr.游戏玩家)
                .FirstOrDefaultAsync(u => u.Id == userId);
        }

        /// <summary>
        /// 获取用户角色列表
        /// </summary>
        public async Task<List<玩家角色>> 获取用户角色列表(Guid userId)
        {
            return await 数据库上下文.玩家角色表
                .Include(pr => pr.游戏玩家)
                .Where(r => r.用户Id == userId)
                .ToListAsync();
        }

        /// <summary>
        /// 验证管理员权限
        /// </summary>
        public async Task<bool> 验证管理员权限(Guid userId)
        {
            var 用户 = await 数据库上下文.用户表.FindAsync(userId);
            return 用户?.是管理员 ?? false;
        }
    }
}